package me.zhengjie.minbearwcs.serivce.rework;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.minbearwcs.dao.rework.inf.ReworkOrderDao;
import me.zhengjie.minbearwcs.dao.rework.inf.ReworkOrderDetailDao;
import me.zhengjie.minbearwcs.dao.rework.inf.ReworkOrderDetailHistoryDao;
import me.zhengjie.minbearwcs.dao.rework.inf.ReworkOrderHistoryDao;
import me.zhengjie.minbearwcs.entity.DTO.response.Resp;
import me.zhengjie.minbearwcs.entity.DTO.rework.wms.order.WmsReworkOrder;
import me.zhengjie.minbearwcs.entity.DTO.transfer.Tuple;
import me.zhengjie.minbearwcs.entity.PO.wcs.rework.ReworkOrder;
import me.zhengjie.minbearwcs.entity.PO.wcs.rework.ReworkOrderDetail;
import me.zhengjie.minbearwcs.entity.PO.wcs.rework.history.ReworkOrderDetailHistory;
import me.zhengjie.minbearwcs.entity.PO.wcs.rework.history.ReworkOrderHistory;
import me.zhengjie.minbearwcs.entity.PO.wcs.rework.status.ReworkOrderDetailStatus;
import me.zhengjie.minbearwcs.entity.PO.wcs.rework.status.ReworkOrderStatus;
import me.zhengjie.minbearwcs.serivce.mission.generate.MissionGeneratorCollector;
import me.zhengjie.minbearwcs.serivce.mission.generate.type.MissionGenType;
import me.zhengjie.minbearwcs.serivce.mission.locker.StorageLockCollector;
import me.zhengjie.minbearwcs.utils.IdWorker;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class ReworkService {

    private final ReworkOrderDao reworkOrderDao;
    private final ReworkOrderDetailDao reworkOrderDetailDao;
    private final IdWorker idWorker;
    private final MissionGeneratorCollector missionGeneratorCollector;
    private final ReworkOrderHistoryDao reworkOrderHistoryDao;
    private final ReworkOrderDetailHistoryDao reworkOrderDetailHistoryDao;



    public Tuple<String> reworkOrderReceive(WmsReworkOrder wmsReworkOrder) {
        //  TODO: 套锁
        synchronized (StorageLockCollector.lockStorage5FOr6F){
            return innerReworkOrderReceive(wmsReworkOrder);
        }
    }

    @Transactional
    public Tuple<String> innerReworkOrderReceive(WmsReworkOrder wmsReworkOrder) {
        //  TODO: 套锁

        if (wmsReworkOrder.getPalletList().isEmpty()){
            return Tuple.tuple("移库栈板列表为空，下发失败",false);
        }

        ReworkOrder reworkOrder = new ReworkOrder(null, wmsReworkOrder.getReworkOrderCode(), wmsReworkOrder.getOrderType(), ReworkOrderStatus.PROCESSING,
                LocalDateTime.now(), LocalDateTime.now(), null);
        reworkOrderDao.insert(reworkOrder);

        List<String> palletList = wmsReworkOrder.getPalletList();
        List<ReworkOrderDetail> reworkOrderDetails = new ArrayList<>();
        for (String pallet : palletList) {
            ReworkOrderDetail reworkOrderDetail = new ReworkOrderDetail(null, "rework_detail_" + idWorker.nextId(),
                    wmsReworkOrder.getReworkOrderCode(), pallet,
                    ReworkOrderDetailStatus.INIT);

            reworkOrderDetailDao.insert(reworkOrderDetail);
            reworkOrderDetails.add(reworkOrderDetail);
        }

        missionGeneratorCollector.getGenerator(MissionGenType.REWORK).generate(reworkOrderDetails);

        return Tuple.tuple(null, true);
    }


    @Transactional
    public Tuple<String> reworkOrderComplete(String reworkOrderCode) {
        ReworkOrder reworkOrder = reworkOrderDao.selectByReworkOrderCode(reworkOrderCode);
        if(reworkOrder == null){
            return Tuple.tuple("返工单不存在，结束失败",false);
        }

        Long notCompleteNum = reworkOrderDetailDao.selectExcludeStatusCountByReworkOrderCode(reworkOrderCode, ReworkOrderDetailStatus.COMPLETE);
        if (notCompleteNum>0){
            return Tuple.tuple("还有栈板未完成，结束失败",false);
        }

        List<ReworkOrderDetail> reworkOrderDetailList = reworkOrderDetailDao.selectByReworkOrderCode(reworkOrderCode);
        for (ReworkOrderDetail reworkOrderDetail : reworkOrderDetailList) {
            reworkOrderDetail.setStatus(ReworkOrderDetailStatus.COMPLETE);
            reworkOrderDetailHistoryDao.insert(
                    new ReworkOrderDetailHistory(null,reworkOrderDetail.getReworkOrderDetailCode(),reworkOrderDetail.getReworkOrderCode(),
                            reworkOrderDetail.getPalletCode(),reworkOrderDetail.getStatus())
            );
            reworkOrderDetailDao.deleteById(reworkOrderDetail.getId());
        }

        reworkOrder.setStatus(ReworkOrderStatus.COMPLETE);
        reworkOrder.setFinishTime(LocalDateTime.now());
        reworkOrderHistoryDao.insert(
                new ReworkOrderHistory(null,reworkOrder.getReworkOrderCode(),reworkOrder.getOrderType(),reworkOrder.getStatus(),
                        reworkOrder.getDispatchTime(),reworkOrder.getStartTime(),reworkOrder.getFinishTime())
        );
        reworkOrderDao.deleteById(reworkOrder.getId());

        return Tuple.tuple(null,true);
    }

}
